package com.suray.wcs.service.pojo.rgv.rgv.protocol.base;

import com.suray.wcs.service.pojo.Rgv;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

public abstract class RgvSendMessage extends RgvBaseMessage {

    protected static Map<MessageLifeKey, Integer> lifeMap = new HashMap<>();
    private MessageLifeKey lifeKey;

    protected int getLife() {
        int life = lifeMap.get(lifeKey);
        if (life == 255) {
            life = 0;
            lifeMap.put(lifeKey, life);
            return life;
        }

        lifeMap.put(lifeKey, ++life);
        return life;
    }

    public RgvSendMessage(Rgv rgv, String clazz) {
        super(rgv, clazz);
        lifeKey = new MessageLifeKey(rgv, clazz);
        if (lifeMap.get(lifeKey) == null) {
            lifeMap.put(lifeKey, 0);
        }
    }

    protected abstract void setCrc(int crc);

    protected abstract void setLength(int length);

    public byte[] makeMessage() {
        //TODO 连续计算两次message，需优化
        byte[] data = super.makeMessage();
        setLength(data.length);
        data = super.makeMessage();
        setCrc(calcCrc(data, data.length - 4));
        return super.makeMessage();
    }

    protected void setDefaultValue() {
        setValue("firstFrame", 0x2FD);
        setValue("deviceId", getRgv().getRgvDB().getRgvNo());
        setValue("version", 1);
        setValue("endFrame", 0x3FC);
        setValue("life", getLife());
    }

    class MessageLifeKey {
        private Rgv rgv;
        private String clazz;

        private MessageLifeKey(Rgv rgv, String clazz) {
            this.rgv = rgv;
            this.clazz = clazz;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
            MessageLifeKey that = (MessageLifeKey) o;
            return Objects.equals(rgv, that.rgv) &&
                    Objects.equals(clazz, that.clazz);
        }

        @Override
        public int hashCode() {
            return Objects.hash(rgv, clazz);
        }
    }

}
